﻿Imports Microsoft.DirectX
''' <summary>
''' Dieses Objekt zeichnet den Spielverlauf auf.
''' </summary>
''' <remarks></remarks>
<Serializable()> Public Class ObjektAufzeichnungen
    Public Enum Rang
        S
        A
        B
        C
        D
    End Enum
    Public Aufzeichnungen As TagAufzeichnung() = {}
    Public BesondereEreignisse() As BesonderesEreigniss = {}
    Public DestroyedUnits(Objektverwalter.Spielfeld.Spieler.Length - 2) As Int64
    Public LostUnits(Objektverwalter.Spielfeld.Spieler.Length - 2) As Int64
    Public Damage(Objektverwalter.Spielfeld.Spieler.Length - 2) As Int64
    Public AttackNumbers(Objektverwalter.Spielfeld.Spieler.Length - 2) As Int64
    Public DeployedUnits(Objektverwalter.Spielfeld.Spieler.Length - 2) As Int64

    Public Sub New(ByVal StartSpieler As Integer)
        Array.Resize(Aufzeichnungen, 1)
        Aufzeichnungen(0) = New TagAufzeichnung()
    End Sub
    ''' <summary>
    ''' Macht ein Update der Aufzeichnungen, wird immer am RundenAnfang und Runden Ende ausgeführt.
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub UpdateAufzeichnungen(ByVal RundenAnfang As Boolean, Optional ByVal SpielEnde As Boolean = False)
        If Aufzeichnungen(Aufzeichnungen.Length - 1).UpdateAufzeichnungen(RundenAnfang) Then
            If SpielEnde = False Then
                Array.Resize(Aufzeichnungen, Aufzeichnungen.Length + 1)
                Aufzeichnungen(Aufzeichnungen.Length - 1) = New TagAufzeichnung()
            End If
        End If
    End Sub
    Public Sub AddEreignis(ByVal Spieler As Integer, ByVal Tag As Integer, ByVal E As BesonderesEreigniss.Ereignisse)
        Array.Resize(BesondereEreignisse, BesondereEreignisse.Length + 1)
        BesondereEreignisse(BesondereEreignisse.Length - 1) = New BesonderesEreigniss(Spieler, Tag, E)
    End Sub
    ''' <summary>
    ''' Berechnet den Rang dieses Spielers
    ''' </summary>
    ''' <param name="Spielfeld"></param>
    ''' <param name="Spieler"></param>
    ''' <param name="PunkteVerteilung">X=Speed, Y=Power, Z=Technique</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CalculateRang(ByVal Spielfeld As ObjektSpielfeld, ByVal Spieler As Integer, ByRef PunkteVerteilung As vector3) As Rang
        Dim Punkte As Integer = 0
        Dim MapSize As Integer = Spielfeld.GetSpielgröße
        Dim MTime As Integer = 0
        If Spielfeld.Regeln.MaxTime <= 0 Then
            MTime = (Spielfeld.Höhe + Spielfeld.Breite) / 5 * 2
        Else
            MTime = Spielfeld.Regeln.MaxTime
        End If
        If Spielfeld.Runde < MTime Then
            PunkteVerteilung.X = 200 - (Spielfeld.Runde * (100 / MTime))
        Else
            PunkteVerteilung.X = 100 - ((Spielfeld.Runde - MTime) * (100 / (3 * MTime)))
        End If

        Dim P1 As Integer = (Damage(Spieler - 1) + (DestroyedUnits(Spieler - 1) * 100))
        If AttackNumbers(Spieler - 1) > 0 Then
            P1 /= AttackNumbers(Spieler - 1)
        Else
            P1 = 0
        End If
        If P1 >= 100 Then
            PunkteVerteilung.Y += P1
        ElseIf P1 > 50 Then
            PunkteVerteilung.Y += (2 * P1) - 100
        Else
            PunkteVerteilung.Y += P1
        End If

        Dim Truppenlimit As Integer = 0
        If Spielfeld.Regeln.MaxDeployedUnits <= 0 Then
            Truppenlimit = Math.DivRem(MapSize, 17, 0)
        Else
            Truppenlimit = Spielfeld.Regeln.MaxDeployedUnits
        End If
        Dim PTeiler As Integer = (DeployedUnits(Spieler - 1) + LostUnits(Spieler - 1))
        If PTeiler > 0 Then
            PunkteVerteilung.Z = (Truppenlimit / PTeiler) * 75
        Else
            PunkteVerteilung.Z = 150
        End If
        Punkte = PunkteVerteilung.X + PunkteVerteilung.Y + PunkteVerteilung.Z
        'Rang auswählen
        Return GetRank(Punkte)
    End Function
    Public Shared Function GetRank(ByVal Punkte As Integer) As Rang
        Select Case Punkte
            Case Is >= 330
                Return Rang.S
            Case Is >= 280
                Return Rang.A
            Case Is >= 250
                Return Rang.B
            Case Is >= 200
                Return Rang.C
            Case Else
                Return Rang.D
        End Select
    End Function
    Public Sub UpdateAngriff(ByVal Damage As Integer, ByVal Spieler As Integer)
        AttackNumbers(Spieler - 1) += 1
        Me.Damage(Spieler - 1) += Damage
    End Sub
End Class
''' <summary>
''' Die Aufzeichnungen einer Runde
''' </summary>
''' <remarks></remarks>
<Serializable()> Public Class TagAufzeichnung
    Public SpielerAufzeichnungen As Aufzeichnung(,) = {}
    Public Sub New()
        ReDim SpielerAufzeichnungen(Objektverwalter.Spielfeld.Spieler.Length - 2, 1)
    End Sub
    ''' <summary>
    ''' Macht ein Update der Aufzeichnung
    ''' </summary>
    ''' <param name="RundenAnfang"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function UpdateAufzeichnungen(ByVal RundenAnfang As Boolean) As Boolean
        Dim Stelle As Integer = 0
        If RundenAnfang = False Then Stelle = 1
        Dim Spieler As Integer = Objektverwalter.Spielfeld.AktuellerSpieler.Spieler
        SpielerAufzeichnungen(Spieler - 1, Stelle) = New Aufzeichnung(Objektverwalter.Spielfeld.Runde, Spieler, Objektverwalter.Spielfeld.AktuellerSpieler.Fonds, _
                                                               Objektverwalter.Spielfeld.AktuellerSpieler.Einkommen, Objektverwalter.Spielfeld.AktuellerSpieler.CountBuildings, Objektverwalter.Spielfeld.AktuellerSpieler.CountUnits, _
                                                               Objektverwalter.Spielfeld.AktuellerSpieler.CalculateSpielerStärke)
        If Objektverwalter.Spielfeld.Runde = 1 Then
            If Spieler > 1 Then
                If SpielerAufzeichnungen(0, 0) Is Nothing Then
                    'Der Startspieler ist nicht Spieler 1 
                    For I = 0 To Spieler - 2
                        SpielerAufzeichnungen(I, 0) = New Aufzeichnung(Objektverwalter.Spielfeld.Runde, I + 1, Objektverwalter.Spielfeld.Spieler(I + 1).Fonds, _
                                                                  Objektverwalter.Spielfeld.Spieler(I + 1).Einkommen, Objektverwalter.Spielfeld.Spieler(I + 1).CountBuildings, Objektverwalter.Spielfeld.Spieler(I + 1).CountUnits, _
                                                                  Objektverwalter.Spielfeld.Spieler(I + 1).CalculateSpielerStärke)
                        SpielerAufzeichnungen(I, 1) = New Aufzeichnung(Objektverwalter.Spielfeld.Runde, I + 1, Objektverwalter.Spielfeld.Spieler(I + 1).Fonds, _
                                                         Objektverwalter.Spielfeld.Spieler(I + 1).Einkommen, Objektverwalter.Spielfeld.Spieler(I + 1).CountBuildings, Objektverwalter.Spielfeld.Spieler(I + 1).CountUnits, _
                                                         Objektverwalter.Spielfeld.Spieler(I + 1).CalculateSpielerStärke)

                    Next
                End If
            End If
        End If

        If RundenAnfang = False Then
            If Spieler = Objektverwalter.Spielfeld.Spieler.Length - 1 Then
                Return True
            End If
        End If
        Return False
    End Function
End Class
''' <summary>
''' Eine Aufzeichnung von einem Tag von einem Spieler.
''' </summary>
''' <remarks></remarks>
<Serializable()> Public Class Aufzeichnung
    ''' <summary>
    ''' Der Tag der Aufzeichnung
    ''' </summary>
    ''' <remarks></remarks>
    Public Tag As Integer = 0
    ''' <summary>
    ''' Der Spieler von dem die Aufzeichnung ist.
    ''' </summary>
    ''' <remarks></remarks>
    Public Spieler As Integer = 0
    ''' <summary>
    ''' Das Geld, welches er hat.
    ''' </summary>
    ''' <remarks></remarks>
    Public Fonds As Integer = 0
    ''' <summary>
    ''' Sein Einkommen
    ''' </summary>
    ''' <remarks></remarks>
    Public Einkommen As Integer = 0
    ''' <summary>
    ''' Die Gebäude die er hat.
    ''' </summary>
    ''' <remarks></remarks>
    Public Basen As Integer = 0
    ''' <summary>
    ''' Die Truppen unter seiner Kontrolle
    ''' </summary>
    ''' <remarks></remarks>
    Public Einheiten As Integer = 0
    ''' <summary>
    ''' Die Stärke dieses Spielers in Punkten.
    ''' </summary>
    ''' <remarks></remarks>
    Public SpielerStärke As Integer = 0
    Public Sub New(ByVal Tag As Integer, ByVal Spieler As Integer, ByVal Fonds As Integer, ByVal Einkommen As Integer, ByVal Basen As Integer _
                   , ByVal Einheiten As Integer, ByVal Spielerstärke As Integer)

        Me.Tag = Tag
        Me.Spieler = Spieler
        If Objektverwalter.Spielfeld.Regeln.IstBesiegt(Spieler) Then
            Me.Fonds = -1
            Me.Einkommen = -1
            Me.Einheiten = -1
            Me.SpielerStärke = -1
            Me.Basen = -1
        Else
            Me.Fonds = Fonds
            Me.Einkommen = Einkommen
            Me.Einheiten = Einheiten
            Me.Basen = Basen
            Me.SpielerStärke = Spielerstärke
        End If
    End Sub
End Class
''' <summary>
''' Zeichnet ein besonderes Ereignis auf.
''' </summary>
''' <remarks></remarks>
<Serializable()> Public Class BesonderesEreigniss
    Enum Ereignisse
        Gabe
        Spezialgabe
        Doppelgabe
        HQEroberung
        HQVerlust

    End Enum
    Public Spieler As Integer
    Public Tag As Integer
    Public Ereignis As Ereignisse
    Public Sub New(ByVal Spieler As Integer, ByVal Tag As Integer, ByVal Ereignis As Ereignisse)
        Me.Spieler = Spieler
        Me.Tag = Tag
        Me.Ereignis = Ereignis
    End Sub
End Class